package com.sjsu.cmpe239.evaluationTests;

import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.common.Weighting;
import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
import org.apache.mahout.cf.taste.eval.RecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.eval.AverageAbsoluteDifferenceRecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.eval.RMSRecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.model.jdbc.AbstractJDBCDataModel;
import org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel;
import org.apache.mahout.cf.taste.impl.recommender.slopeone.SlopeOneRecommender;
import org.apache.mahout.cf.taste.impl.recommender.slopeone.jdbc.MySQLJDBCDiffStorage;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.recommender.slopeone.DiffStorage;
import org.junit.BeforeClass;
import org.junit.Test;

import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

public class SlopeOneRecommenderEvalatorTest {

	static AbstractJDBCDataModel model;

	@BeforeClass
	public static void buildDataModel() {
		MysqlDataSource dataSource = new MysqlConnectionPoolDataSource();
		dataSource.setServerName("localhost");
		dataSource.setUser("root");
		dataSource.setPassword("");
		dataSource.setDatabaseName("239db");

		model = new MySQLJDBCDataModel(dataSource, "ratings",
				"Id", "MoviesId", "Rating", "Timestamp");

	}

	/*
	 *
	 */
	@Test
	public void evaluateSlopeOneRecommemder() throws TasteException {

		// Start: evaluate with Average absolute difference
		RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
		RecommenderBuilder builder = new RecommenderBuilder() {
			@Override
			public Recommender buildRecommender(DataModel model)
					throws TasteException {

				return new SlopeOneRecommender(model);

			}
		};

		double score = evaluator.evaluate(builder, null, model, 0.7, 1.0);
		System.out.println("\n evaluateSlopeOneRecommemder");
		System.out
				.println("AverageAbsoluteDifferenceEvaluator score: " + score);

		// Start: evaluate with RMSRecommenderEvaluator
		evaluator = new RMSRecommenderEvaluator();
		score = evaluator.evaluate(builder, null, model, 0.7, 1.0);
		System.out.println("RMSEvaluator score: " + score);

		/*
		 * RecommenderIRStatsEvaluator irStatsEvaluator = new
		 * GenericRecommenderIRStatsEvaluator(); IRStatistics stats =
		 * irStatsEvaluator.evaluate(builder, null, model, null, 2, 1.0, 1.0);
		 * System.out.println("IRStatistics precision: " +
		 * stats.getPrecision()); System.out.println("IRStatistics recall: " +
		 * stats.getRecall());
		 */

	}

	@Test
	public void evaluateSlopeOneRecommemderWithWeighting() throws TasteException {

		// Start: evaluate with Average absolute difference
		RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
		RecommenderBuilder builder = new RecommenderBuilder() {
			@Override
			public Recommender buildRecommender(DataModel model)
					throws TasteException {
				DiffStorage diffStorage = new MySQLJDBCDiffStorage(
						(AbstractJDBCDataModel) model);
				return new SlopeOneRecommender(model, Weighting.WEIGHTED,
						Weighting.WEIGHTED, diffStorage);

			}
		};

		double score = evaluator.evaluate(builder, null, model, 0.7, 1.0);
		System.out.println("\nevaluateUserBasedRecWithPearson");
		System.out
				.println("AverageAbsoluteDifferenceEvaluator score: " + score);

		// Start: evaluate with RMSRecommenderEvaluator
		evaluator = new RMSRecommenderEvaluator();
		score = evaluator.evaluate(builder, null, model, 0.7, 1.0);
		System.out.println("RMSEvaluator score: " + score);

		/*
		 * RecommenderIRStatsEvaluator irStatsEvaluator = new
		 * GenericRecommenderIRStatsEvaluator(); IRStatistics stats =
		 * irStatsEvaluator.evaluate(builder, null, model, null, 2, 1.0, 1.0);
		 * System.out.println("IRStatistics precision: " +
		 * stats.getPrecision()); System.out.println("IRStatistics recall: " +
		 * stats.getRecall());
		 */

	}

}
